# -*- coding: UTF-8 -*-
import os
import sys
import math
import numpy as np
from haversine import haversine  # 导入haversine库，用于计算两点间的球面距离
from object import funcs_n2  # 导入自定义模块funcs_n2

# 将上级目录加入系统路径，以便导入上级目录中的模块
sys.path.append(os.path.join(os.path.dirname(__file__), ".."))

# import wifi_spec  # 该行被注释，可能用于WiFi相关的计算


def path_loss(d, n=6, A=-5):
    """
    计算路径损耗（Path Loss）
    :param d: 距离（d ≤ 1，若d > 1，则重设为1）
    :param n: 路径损耗因子，默认值为6
    :param A: 参考损耗，默认值为-5
    :return: 计算得到的路径损耗值
    """
    if d > 1:
        d = 1  # 距离限制为1，以避免不合理的计算
    return 10 * n * math.log10(d) + A  # 路径损耗计算公式


def bts_distance(lat1, lon1, lat2, lon2):
    """
    计算两点之间的球面距离（基站与用户设备的距离）
    :param lat1: 点1的纬度
    :param lon1: 点1的经度
    :param lat2: 点2的纬度
    :param lon2: 点2的经度
    :return: 两点之间的球面距离（单位：千米）
    """
    a = (lat1, lon1)
    b = (lat2, lon2)
    distance = haversine(a, b)  # 使用haversine公式计算两点间的球面距离
    return distance


def hop_distance(lat1, lon1, lat2, lon2):
    """
    计算两点之间的欧几里得距离（假设地球是平面）
    :param lat1: 点1的纬度
    :param lon1: 点1的经度
    :param lat2: 点2的纬度
    :param lon2: 点2的经度
    :return: 计算得到的欧几里得距离
    """
    # 归一化GPS坐标（可能是对经纬度进行一定转换，确保计算准确）
    lat1, lon1 = funcs_n2.normalizeGPS(lat1, lon1)
    lat2, lon2 = funcs_n2.normalizeGPS(lat2, lon2)

    # 计算欧几里得距离（简单的直线距离计算方式）
    distance = math.sqrt(math.pow(lat1 - lat2, 2) + math.pow((lon1 - lon2), 2))
    return distance


def trans_dly(task_size, pos_ux, pos_uy, pos_ex, pos_ey, bw, power=23, noise=174):
    """
    计算传输时延（Transmission Delay）
    :param task_size: 任务大小（数据量）
    :param pos_ux: 用户设备的纬度
    :param pos_uy: 用户设备的经度
    :param pos_ex: 边缘服务器的纬度
    :param pos_ey: 边缘服务器的经度
    :param bw: 传输带宽（带宽决定最大传输速率）
    :param power: 发射功率，默认值为23dBm
    :param noise: 噪声功率，默认值为174dBm
    :return: 传输时延、设备与边缘服务器之间的距离、理论传输速率
    """
    bts_d = bts_distance(
        pos_ux, pos_uy, pos_ex, pos_ey
    )  # 计算用户设备与边缘服务器的距离
    pth_loss = path_loss(bts_d)  # 计算路径损耗

    # Shannon公式计算信道容量（理论传输速率）
    trate = bw * math.log2(1 + power * pow(pth_loss, 2) / (bw * noise))

    tmp2 = task_size / trate  # 计算传输时延（任务大小 / 传输速率）

    return tmp2, bts_d, trate  # 返回传输时延、距离和理论传输速率


if __name__ == "__main__":
    pass
